package com.lyon.demo.storage.client.core;

import cn.hutool.core.text.CharSequenceUtil;
import com.lyon.demo.storage.client.api.core.config.DLedgerConfig;
import com.lyon.demo.storage.client.api.core.config.StoreConfig;
import com.lyon.demo.storage.client.api.core.core.Entry;
import com.lyon.demo.storage.client.api.core.core.StorageManager;
import com.lyon.demo.storage.client.core.consistency.ConsistencyService;
import com.lyon.demo.storage.client.api.core.protocol.storage.Protocols;
import com.lyon.demo.storage.common.spi.DefaultSpiLoader;
import lombok.Data;

import java.util.concurrent.CompletableFuture;

/**
 * @author LeeYan9
 * @since 2022-05-10
 */
@Data
public class DelegateStoreManager<K, V> implements StorageManager<K, V> {

    private final DLedgerConfig storeConfig;
    private ConsistencyService<K, V, StoreConfig> delegate;


    @SuppressWarnings("unchecked")
    public DelegateStoreManager(DLedgerConfig storeConfig) {
        this.storeConfig = storeConfig;
        if (!enableRaftStore(storeConfig.getStoreProtocol())) {
            return;
        }
        this.delegate = DefaultSpiLoader.INSTANCE.loader(ConsistencyService.class, storeConfig.getStoreProtocol());
        this.delegate.prepare(storeConfig);
    }

    private boolean enableRaftStore(String storeProtocol) {
        return CharSequenceUtil.equals(Protocols.RAFT, storeProtocol);

    }

    @Override
    public void startup() {
        this.delegate.startup();
    }

    @Override
    public void shutdown() {
        this.delegate.shutdown();
    }

    @Override
    public <R extends Entry> CompletableFuture<R> commit(K data) {
        return delegate.commit(data);
    }

    @Override
    public <R extends Entry> CompletableFuture<R> commitEntry(K key, V value) {
        return delegate.commitEntry(key, value);
    }

    @Override
    public <R extends Entry> CompletableFuture<R> commitEntry(String tag, K key, V value) {
        return delegate.commitEntry(tag, key, value);
    }

    @Override
    public <R> CompletableFuture<R> get(long index) {
        return delegate.get(index);
    }

    @Override
    public <R extends Entry> CompletableFuture<R> get(String tag, K key) {
        return delegate.get(tag, key);
    }

    @Override
    public <R extends Entry> CompletableFuture<R> get(K key) {
        return delegate.get(key);
    }
}
